package com.example.function.integration.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

@Slf4j
@Configuration
@EnableCaching
public class RedisConfig {

    @Value("${spring.redis.database}")
    private String redisDatabase;

    @Value("${spring.redis.port}")
    private String redisPort;

    @Value("${spring.redis.default.host}")
    private String defaultHost;

    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        log.info(".................初始化RedisTemplate.................");
        RedisTemplate<String, Object> redisTemplate;
        String hostNameS = lettuceConnectionFactory.getStandaloneConfiguration().getHostName();
        // 需求决定，优先使用 服务器下此目录（/zdxlz/etc/ha/default_vip）下得 redis host地址
        try {
            BufferedReader br = new BufferedReader(new FileReader(defaultHost));
            String defaultRedisHost = br.readLine();
            if (StringUtils.isNotBlank(defaultRedisHost)) {
                redisTemplate = getRedisTemplate(getLettuceConnectionFactory(defaultRedisHost));
            } else {
                log.info(".................初始化Redis从节点对象工厂...从节点redis-host:{}.................", hostNameS);
                redisTemplate = getRedisTemplate(lettuceConnectionFactory);
            }
        } catch (IOException ignored) {
            log.error("设备中不存在默认的Redis配置文件，使用项目YML文件中的redis-host地址:{}", hostNameS);
            redisTemplate = getRedisTemplate(lettuceConnectionFactory);
        }
        log.info(".................初始化RedisTemplate完成.................");
        return redisTemplate;
    }

    /**
     * @Description：通过reids对象工厂初始化RedisTemplate
     * @Author：fengcheng
     * @Date：2024/10/29 15:38
     * @Param：lettuceConnectionFactory
     * @ParamsType：[org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory]
     * @Return：org.springframework.data.redis.core.RedisTemplate<java.lang.String,java.lang.Object>
     */
    private RedisTemplate<String, Object> getRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<?> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);// key序列化
        redisTemplate.setValueSerializer(stringSerializer);// value序列化
        redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        redisTemplate.setHashValueSerializer(stringSerializer);// Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * @Description：初始化Redis主节点对象工厂
     * @Author：fengcheng
     * @Date：2024/10/29 15:37
     * @Param：hostName
     * @ParamsType：[java.lang.String]
     * @Return：org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
     */
    public LettuceConnectionFactory getLettuceConnectionFactory(String hostName) {
        log.info(".................初始化Redis主节点对象工厂...主节点redis-host:{}.................", hostName);
        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();
        lettuceConnectionFactory.getStandaloneConfiguration().setHostName(hostName);
        lettuceConnectionFactory.getStandaloneConfiguration().setPort(Integer.parseInt(redisPort));
        lettuceConnectionFactory.getStandaloneConfiguration().setDatabase(Integer.parseInt(redisDatabase));
        lettuceConnectionFactory.afterPropertiesSet();
        log.info(".................初始化Redis主节点对象工厂完成.................");
        return lettuceConnectionFactory;
    }

}
